#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using Utilities.Collections;
using Utilities.Testing;
using NUnit.Framework;
using Utilities.Miscellaneous;
using System.Globalization;

namespace Utilities.Test.Miscellaneous
{
  public class RandomUtilsFixture : TestFixtureBase
  {
    [Test]
    public void GetUInt32()
    {
      List<uint> results = new List<uint>(EnumerableUtils.Create<uint>(delegate { return RandomUtils.GetUInt32(); }, 1000));

      List<AssertTest<uint>> tests = new List<AssertTest<uint>>();
      tests.Add(new AssertTest<uint>(delegate(uint v) { return v > 0; }, "Greater than zero."));
      tests.Add(new AssertTest<uint>(delegate(uint v) { return v > int.MaxValue; }, "Greater than max Int32."));

      TestingUtils.TestCollection<uint>(results, tests);
    }

    [Test]
    public void GetInt64()
    {
      List<long> results = new List<long>(EnumerableUtils.Create<long>(delegate { return RandomUtils.GetInt64(); }, 1000));

      List<AssertTest<long>> tests = new List<AssertTest<long>>();
      tests.Add(new AssertTest<long>(delegate(long v) { return v > 0; }, "Greater than zero."));
      tests.Add(new AssertTest<long>(delegate(long v) { return v > int.MaxValue; }, "Greater than max Int32."));

      TestingUtils.TestCollection<long>(results, tests);
    }

    [Test]
    public void GetUInt64()
    {
      List<ulong> results = new List<ulong>(EnumerableUtils.Create<ulong>(delegate { return RandomUtils.GetUInt64(); }, 1000));

      List<AssertTest<ulong>> tests = new List<AssertTest<ulong>>();
      tests.Add(new AssertTest<ulong>(delegate(ulong v) { return v > 0; }, "Greater than zero."));
      tests.Add(new AssertTest<ulong>(delegate(ulong v) { return v > long.MaxValue; }, "Greater than max Int64."));

      TestingUtils.TestCollection<ulong>(results, tests);
    }

    [Test]
    public void GetBoolean()
    {
      List<bool> results = new List<bool>(EnumerableUtils.Create<bool>(delegate { return RandomUtils.GetBoolean(); }, 1000));

      List<AssertTest<bool>> tests = new List<AssertTest<bool>>();
      tests.Add(new AssertTest<bool>(delegate(bool v) { return v; }, "Boolean true."));
      tests.Add(new AssertTest<bool>(delegate(bool v) { return !v; }, "Boolean false."));

      TestingUtils.TestCollection<bool>(results, tests);
    }

    [Test]
    public void GetDouble()
    {
      List<double> results = new List<double>(EnumerableUtils.Create<double>(delegate { return RandomUtils.GetDouble(); }, 1000));



      List<AssertTest<double>> tests = new List<AssertTest<double>>();
      tests.Add(new AssertTest<double>(delegate(double v) { return v < 0; }, "Less than zero."));
      tests.Add(new AssertTest<double>(delegate(double v) { return v > 0; }, "Greater than zero."));
      tests.Add(new AssertTest<double>(delegate(double v) { return v < (double.MinValue / 2); }, "Less than zero."));
      tests.Add(new AssertTest<double>(delegate(double v) { return v > 0; }, "Greater than zero."));

      List<Range<double>> ranges = MathUtils.DivideRange(new Range<double>(double.MinValue / 2, double.MaxValue / 2), 10);

      foreach (Range<double> range in ranges)
      {
        tests.Add(new AssertTest<double>(delegate(double v)
                                         {
                                           return range.InRange(v);
                                         }, range.ToString()));
      }

      TestingUtils.TestCollection<double>(results, tests);
    }

    [Test]
    public void GetAsciiString()
    {
      for (int i = 0; i < 100; i++)
      {
        string randomString = RandomUtils.GetAsciiString(20);

        Assert.AreEqual(20, randomString.Length);

        for (int j = 0; j < randomString.Length; j++)
        {
          int charValue = randomString[j];
          Assert.IsTrue(charValue >= 32 && charValue <= 126, charValue.ToString());
        }
      }
    }

    [Test]
    public void GetLatinString()
    {
      for (int i = 0; i < 100; i++)
      {
        string randomString = RandomUtils.GetLatinString(20);

        Assert.AreEqual(20, randomString.Length);

        for (int j = 0; j < randomString.Length; j++)
        {
          int charValue = randomString[j];
          Assert.IsTrue(charValue >= 32 && charValue <= 255, charValue.ToString());
        }
      }
    }

    [Test]
    public void GetUnicodeString()
    {
      for (int i = 0; i < 1000; i++)
      {
        string randomString = RandomUtils.GetUnicodeString(20);

        Assert.AreEqual(20, randomString.Length);
      }
    }
  }
}